package com.zxq.ruoyi.channel;

import com.zxq.exchange.ExchangeDTO;
import com.zxq.exchange.observer.INotifyPlatform;
import com.zxq.ruoyi.channel.device.DeviceMessageServiceImpl;
import com.zxq.ruoyi.channel.translator.impl.TransformServiceImpl;
import com.zxq.ruoyi.domain.*;
import com.zxq.ruoyi.domain.vo.DevCmdVo;
import com.zxq.ruoyi.enums.EPlatformCmdType;
import com.zxq.ruoyi.enums.ESponsor;
import com.zxq.ruoyi.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
public class GeneralNotifyPlatform implements INotifyPlatform {

    /**
     * 设备
     */
    @Autowired
    private IotDeviceServiceImpl iotDeviceService;


    /**
     * 设备 -> 产品
     */
    @Autowired
    private IotProductServiceImpl iotProductService;

    /**
     * 协议包 -> 具体指令
     */
    @Autowired
    private IotPacketServiceImpl iotPacketService;

    /**
     * 具体指令 -> 指令解析流程
     */
    @Autowired
    private IotCmdServiceImpl iotCmdService;

    /**
     * 设备消息服务
     */
    @Autowired
    private DeviceMessageServiceImpl deviceMessageService;

    /**
     * 同步消息
     */
    @Autowired
    private SynchroniseMessage synchroniseMessage;

    /**
     * 消息翻译器
     */
    @Autowired
    private TransformServiceImpl transformService;

    /**
     * tcp消息通道
     */
    @Autowired
    private TcpMessageChannel tcpMessageChannel;

    /**
     * 项目产品服务
     */
    @Autowired
    private IotProjectProductServiceImpl projectProductService;


    @Override
    public void notifyPlatform(ExchangeDTO exchangeDTO) {

        log.info("rec dev:" + exchangeDTO.toString());
        String devId = exchangeDTO.getDevId();
        String cmdHex = exchangeDTO.getCmdHex();
        IotDevice iotDeviceDo = new IotDevice();
        iotDeviceDo.setDevId(devId);
        List<IotDevice> iotDeviceDoResults = iotDeviceService.selectIotDeviceList(iotDeviceDo);
        if(iotDeviceDoResults.size() == 0) {
            log.warn(String.format("devId:{0} not register platform",devId));
            return;
        }
        IotDevice  iotDeviceDoResult = iotDeviceDoResults.get(0);

        IotProjectProduct projectProduct = new IotProjectProduct();
        projectProduct.setProjectId(iotDeviceDoResult.getProjectId());
        projectProduct.setProductId(iotDeviceDoResult.getProductId());

        List<IotProjectProduct> iotProjectProducts = projectProductService
                .selectIotProjectProductList(projectProduct);
        if(iotProjectProducts.size() == 0) {
            log.warn(String.format("devId:{0} not reportUrl",devId));
            return;
        }
        //上报地址和令牌
        String reportUrl = iotProjectProducts.get(0).getReportUrl();
        String token =  iotProjectProducts.get(0).getToken();

        IotProduct iotProduct = iotProductService.selectIotProductById(iotDeviceDoResult.getProductId());
        IotPacket iotPacketDo = iotPacketService.selectIotPacketById(iotProduct.getPacketId());
        if(iotPacketDo == null) {
            log.warn(String.format("devId:{0} belong packet is delete",devId));
            return;
        }

        Long packetId = iotPacketDo.getId();
        IotCmd iotCmdDo = new IotCmd();
        iotCmdDo.setPacketId(packetId);
        iotCmdDo.setCmdHex(cmdHex);
        //Sponsor  0 设备 1 平台
        iotCmdDo.setSponsor(ESponsor.device.getValue());
        List<IotCmd> iotCmdResults = iotCmdService.selectIotCmdList(iotCmdDo);
        if(iotCmdResults.size() == 0) {
            log.warn(String.format("devId:{0} cmd({1}) not config",devId,cmdHex));
            return;
        }
        /**
         * 设备指令
         */
        IotCmd iotCmdResult = iotCmdResults.get(0);
        /**
         * 0 指令，需要回复； 1 指令，不需要回复； 2 回复指令；
         */
        Long cmdType = iotCmdResult.getCmdType();
        EPlatformCmdType platformCmdType =  EPlatformCmdType.getType(cmdType.intValue());
        switch (platformCmdType) {
            case CMD: {
                deviceMessageService.deviceReport(exchangeDTO,reportUrl,token);
                DevCmdVo devCmdVo = synchroniseMessage.waitCmdMessage(devId,iotCmdResult.getId());
                log.info("wait message:" + devCmdVo.toString());
                ExchangeDTO resultExchangeDTO = transformService.platTransform(devCmdVo);
                tcpMessageChannel.notifyPlatform(resultExchangeDTO);
            }
            break;
            case NOTICE: {
                deviceMessageService.deviceReport(exchangeDTO,reportUrl,token);
            }
            break;
            case RESULT: {
                deviceMessageService.deviceResult(exchangeDTO);
            }
            break;
        }
    }

}
